import {Vector4} from "../math/Vector4";

export class OutPutBuffer {
    PER_ELEMENT_SIZE = 1;
    public width: number;
    public height: number;
    public imageData: ImageData;

    protected data: Float32Array;

    protected needUpdate: boolean = true;

    private totalSize: number;

    private readonly yFlip: boolean = true;

    protected readonly background: Float32Array;


    calcBackgroundColor(): Vector4 {
        const color = new Vector4(0 ,0 ,0, 255);
        for (let i = 0; i < 4; i++) {
            if ( i < this.PER_ELEMENT_SIZE) {
                color.data[i] = this.background[i] * 255;
            } else {
                if ( i !== 3) {
                    color.data[i] = color.data[this.PER_ELEMENT_SIZE - 1];
                }
            }
        }
        return color;
    }

    constructor(width: number, height: number, elementSize: number, yFlip: boolean) {
        this.PER_ELEMENT_SIZE = elementSize;
        this.yFlip = yFlip;
        this.setSize(width, height);
        this.background = new Float32Array(this.PER_ELEMENT_SIZE);
    }

    setPositionData(x: number, y: number, dataArray: ArrayLike<number>){
        if (dataArray.length > this.PER_ELEMENT_SIZE) {
            for (let i = 0; i < this.PER_ELEMENT_SIZE; i++) {
                this.data[(x + y * this.width) * this.PER_ELEMENT_SIZE + i] = dataArray[i];
            }
        } else {
            this.data.set(dataArray, (x + y * this.width) * this.PER_ELEMENT_SIZE);
        }
        this.needUpdate = true;
    }

    setBackground(background: ArrayLike<number>)  {
        for (let i  = 0; i<this.PER_ELEMENT_SIZE && i < background.length; i++) {
            this.background[i] = background[i];
        }
    }

    setSize(width: number, height: number) {
        this.width =  width;
        this.height = height;
        this.totalSize = width * height * this.PER_ELEMENT_SIZE;
        this.imageData = new ImageData(width, height);
        this.data = new Float32Array(this.totalSize);
        this.needUpdate = true;
    }

    clear() {
        for (let i =0 ; i < this.data.length; i+=this.PER_ELEMENT_SIZE) {
            this.data.set(this.background, i);
        }
        this.needUpdate = true;
    }

    protected elementFillToImage(dataOffset: number, imageOffset: number) {

    }

    protected beforeUpdate() {

    }
    update(): boolean {
        if (this.needUpdate) {
            this.beforeUpdate();
            for (let y = 0; y < this.height; y++) {
                for (let x = 0;  x< this.width; x++) {
                    const sp = (y * this.width + x) * this.PER_ELEMENT_SIZE;
                    const tp = (this.yFlip ? (this.height - y) * this.width + x : y*this.width  + x) * 4;
                    this.elementFillToImage(sp, tp);
                }
            }
            this.needUpdate = false;
            return true;
        }
        return false;
    }

}